/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 *
 * $Id: EnvironmentMeasurementServer.hpp,v 1.2 2009-05-13 07:18:16 amaula Exp $
 *
 * \file
 * \brief MaCI - EnvironmentMeasurement Server interface header.
 * \author Antti Maula <antti.maula@tkk.fi>
 */
#ifndef _MACI_INTERFACE_ENVIRONMENTMEASUREMENTSERVER_HPP_
#define _MACI_INTERFACE_ENVIRONMENTMEASUREMENTSERVER_HPP_
#include "MaCI.hpp"
#include "EnvironmentMeasurementData.hpp"
#include "sync.hpp"
#include "thread.hpp"
#include <list>


// Forward declare gimi::GIMI
namespace gimi {
  class GIMI;
  class GIMIMessage;
}

namespace MaCI {
  namespace EnvironmentMeasurement {

    /** MaCI - EnvironmentMeasurement Server interface
     * 
     * This class contains the methods and types for providing
     * the EnvironmentMeasurement service in the GIMnet.
     */
    class CEnvironmentMeasurementServer : public MaCI::CMaCI
                         // ,private gim::CSync,
                         // private gim::CThread
    {
    public:
      /** Constructor.
       * 
       * Constructor of the EnvironmentMeasurementServer. This requires;
       * a pointer to Initialized and connected GIMI, minor
       * number of this interface (Used as GIMI minor number)
       *
       * @param[in] aMaCICtrlServerPtr Pointer to GIMI used for communication
       * @param[in] aInterfaceMinor Interface minor number. Usually
       * used to indicate the instance of devices of same type.
       * @param[in] aDescription User provided description about
       * service. This description will be appended after text
       * 'MaCI-EnvironmentMeasurementServer; ' in the GIMI service description
       * field.
       * @param[in] aInstanceName Specify Instance name here.
       */
      CEnvironmentMeasurementServer(MaCICtrl::CMaCICtrlServer *aMaCICtrlServerPtr, 
                                    const int aInterfaceMinor,
                                    const std::string &aDescription = "",
                                    const std::string &aInstanceName = "");


      /** Destructor.
       */
      ~CEnvironmentMeasurementServer();
 

           
      /** Return next incoming command in Queue.
       *
       * This function waits for new commands to arrive for a maximum
       * of 'aTimeout_ms' milliseconds. If a command is received, it
       * is stored to reference 'aData', and the function will return
       * KMaCIOK.
       *
       * @param[out] aData      Reference to CEnvironmentMeasurementData to be filled with
       *                        received information.
       * @param[out] aSource    Reference to message source information. This
       *                        is required for example for REPLY operations.
       * @param[in] aTimeout_ms Timeout in milliseconds to sleep waiting
       *                        for the operation to complete. If this
       *                        timeout exceeds and no commands are
       *                        received, this function returns KMaCITimeout.
       *
       * @return                \c 'KMaCIOK' on succesfully received command.\n
       *                        \c 'KMaCITimeout' if timeout value exceeded.\n
       *                        \c 'KMaCIInvalidFormat' if the client received
       *                        a message of invalid format. It is safe to ignore this,
       *                        as it is only a notification for the application
       *                        that an invalid message was received. The event
       *                        is returned as it may help tracing down some
       *                        implementation problems.
       */
      MaCI::EMaCIError WaitCommand(CEnvironmentMeasurementData &aData, 
                                   SMessageSource &aSource,
                                   const unsigned int aTimeout_ms);
       
      /** Send reply to client.
       * 
       * Sends reply to KCommandGetPositionWithEnvironment-query. aData
       * must contain at least TPose2D- and TVariance2D-structures or it 
       * will not be sent to the client side.
       * 
       * @param[in] aData       Reference to CEnvironmentMeasurementData which must
       *                        contain TPose2D and TVariance2D-structures.
       * @param[in] aSource     Reference to message source information. Source information
       *                        is saved at WaitCommand.
       * @return                KMaCIOK, if succesfully sent
       *                        KMaCINoConnection, if there's no connection to hub
       *                        KMaCINotActive, if not Opened
       *                        KMaCIInvalidFormat, if TPose2D or TVariance2D is missing
       *                        
       */
      MaCI::EMaCIError SendReply(const CEnvironmentMeasurementData &aData, 
                                 const SMessageSource &aSource);
    protected:
      /** Open device.
       *
       * Opens the device, basicly registers device to GIMI.
       *  
       * @return                Returns a value of type MaCI::EMaCIError. 
       *                        
       * \see EMaCIError
       */
      MaCI::EMaCIError DoOpen(void);
      
      
      /** Close device.
       *
       * Closes the device. Closes all GIMI registrations and queues.
       *
       * @return                Returns a value of type EMaCIError.
       *
       * \see EMaCIError
       */
      MaCI::EMaCIError DoClose(void);

    private:
      //      int ThreadFunction(const int aThreadNumber); ///< Incoming data handler function
      //      int ProcessMessage(const gimi::GIMIMessage &msg); ///< Incoming data processor function
      bool iServerActive; ///< Is the server active? - flag
      std::string iServiceDescription; ///< User provided service description field.
      unsigned int iEnvironmentMeasurementSequenceNumber;
    };

  }
}


#endif //_MACI_INTERFACE_ENVIRONMENTMEASUREMENTSERVER_HPP_
